#include <stdlib.h>
#include "fatal.h"
#include "Queue.h"

#define MinQueueSize (5)

struct  QueueRecord
{
    int Capacity;
    int Front;
    int Rear;
    int Size;
    ElementType *Array;
};

int IsEmpty( Queue Q )
{
    return Q->Size == 0;
}

int IsFull( Queue Q )
{
    return Q->Size == Q->Capacity;
}

Queue CreateQueue(int MaxElements)
{
    Queue Q;

    if( MaxElements < MinQueueSize )
    {
        Error( "Queue size is too small" );
    }
    Q = malloc(sizeof(struct QueueRecord));
    if (Q == NULL)
    {
        FatalError("Out of space");
    }
    Q->Array = malloc(sizeof(ElementType) * MaxElements);
    if (Q->Array == NULL)
    {
        FatalError("Out of space");
    }
    Q->Capacity = MaxElements;
    MakeEmpty(Q);
    return Q;
}

void DisposeQueue( Queue Q )
{
    if (Q != NULL)
    {
        free(Q->Array);
        free(Q);
    }
}

void MakeEmpty( Queue Q )
{
    Q->Front = 1;
    Q->Rear = 0;
    Q->Size = 0;
}

void EnQueue( ElementType X, Queue Q )
{
    if (IsFull(Q))
    {
        Error("Full Queue");
    }
    Q->Rear++;
    Q->Size++;
    if (Q->Rear >= Q->Capacity)
    {
        Q->Rear = 0;
    } 
    Q->Array[Q->Rear] = X;
}
ElementType Front( Queue Q )
{
    return Q->Array[Q->Front];
}

void Dequeue( Queue Q )
{
    if (IsEmpty(Q))
    {
        Error("Empty queue");
    }
    Q->Front++;
    Q->Size--;
    if (Q->Front >= Q->Capacity)
    {
        Q->Front = 0;
    }
}

ElementType FrontAndDequeue( Queue Q )
{
    int TmpFront = Q->Front;
    Dequeue(Q);
    return Q->Array[TmpFront];
}
